package SGEngine2

import (
	"fmt"
	"github.com/gl"
	"io/ioutil"
)

var (
	ShaderManager    shaderManager
	ShaderFolderPath string = "Shader/"
)

func init() {
	ShaderManager.Init()
}

type shaderManager struct {
	shaders map[string]*Shader
}

func (s *shaderManager) Init() {
	s.shaders = make(map[string]*Shader)
}

func (s *shaderManager) SahderGet(shaderName string) *Shader {
	if s.shaders[shaderName] == nil {
		s.LoadShaderByFile(shaderName)
	}
	return s.shaders[shaderName]
}

func (s *shaderManager) LoadShaderByFile(shaderName string) *Shader {
	vs, err := ioutil.ReadFile(ShaderFolderPath + shaderName + ".V.shader")
	fs, err2 := ioutil.ReadFile(ShaderFolderPath + shaderName + ".F.shader")
	if err != nil && err2 != nil {
		fmt.Println(ShaderFolderPath + shaderName + ".V.shader")
		fmt.Println(shaderName + " not Found")
	}
	return ShaderManager.LoadShader(string(vs), string(fs), shaderName)
}

func (s *shaderManager) LoadShader(VShaderStr, fShaderStr, shaderName string) *Shader {
	if s, ok := s.shaders[shaderName]; ok == true {
		return s
	}
	shader := Shader{
		shaderName,
		gl.CreateShader(gl.VERTEX_SHADER),
		gl.CreateShader(gl.FRAGMENT_SHADER),
		gl.CreateProgram(),
	}
	shader.Load(VShaderStr, fShaderStr)
	s.shaders[shaderName] = &shader
	return &shader
}

type Shader struct {
	ShaderName string
	VShader    gl.Shader
	FShader    gl.Shader
	Program    gl.Program
}

func (s *Shader) Load(VShaderStr, fShaderStr string) {
	s.VShader.Source(VShaderStr)
	s.FShader.Source(fShaderStr)
	s.VShader.Compile()
	s.FShader.Compile()
	s.Program.AttachShader(s.VShader)
	s.Program.AttachShader(s.FShader)
	s.Program.Link()

	fmt.Println(s.Program.GetInfoLog())
}
